package middleware

import (
	"crypto/sha256"
	"encoding/hex"
	"ginx/internal/global/common"
	"ginx/internal/global/configs"
	"ginx/internal/utils"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/mssola/user_agent"
)

func SystemLogger() gin.HandlerFunc {
	return func(c *gin.Context) {

		// 记录请求开始时间
		start := time.Now()

		clientIP := utils.IP.GetIpAddress(c)
		method := c.Request.Method
		path := c.Request.URL.Path
		raw := c.Request.URL.RawQuery
		if raw != "" {
			path = path + "?" + raw
		}

		// 获取客户端的User-Agent和IP地址
		userAgent := c.Request.UserAgent()

		ua := user_agent.New(userAgent)
		browser, _ := ua.Browser()
		os := ua.OS()

		ip := utils.IP.GetIpAddress(c)
		// 生成client_id
		hash := sha256.Sum256([]byte(userAgent + ip))
		client_id := hex.EncodeToString(hash[:])

		// 处理请求
		c.Next()

		// statuscode 需要在Next之后获取，一把是由业务代码设置的
		statusCode := c.Writer.Status()

		// 记录请求结束时间和处理时间
		end := time.Now()
		formattedLatency := utils.FormatLatency(end.Sub(start))

		// 创建ClientInfo对象
		clientInfo := common.ClientInfo{
			ID:         client_id,
			IP:         clientIP,
			Os:         os,
			Browser:    browser,
			UserAgent:  userAgent,
			StatusCode: statusCode,
			Method:     method,
			Path:       path,
			Latency:    formattedLatency,
		}

		// 将client_id保存到上下文中
		c.Set("client_info", clientInfo)

		var service_code int
		var log_msg string

		if value, ok := c.Get("log_msg"); ok {
			if msg, ok := value.(string); ok {
				log_msg = msg
			}
		}

		if value, ok := c.Get("service_code"); ok {
			if code, ok := value.(int); ok {
				service_code = code
			}

		}

		// 输出系统日志
		if configs.C.Logger.HttpRequestLog {
			utils.SystemLogger(c, clientInfo, service_code, log_msg)
		}
	}
}
